﻿using System;
using System.IO;
using System.Text;
using System.Web;
using Karma.Framework.Core.IoC;
using Karma.Framework.Core.Repository;
using Karma.Framework.Core.Services.Invoker;
using Karma.Framework.Core.Services.Invoker.Adapter;
using Karma.Framework.Core.Services.Invoker.Processor;
using log4net;

namespace Karma.Framework.Core.Domain.Tools.Export.Adapter
{
    public class HttpAdapter : IAdapter
    {
        private static ILog LOG = LogManager.GetLogger(typeof(HttpAdapter).Name);

        public HttpAdapter(IProcessor processor)
        {
            Processor = processor;
        }

        protected IProcessor Processor { get; set; }

        public virtual ServiceRequest ReadRequest()
        {
            var request = HttpContext.Current.Request;
            #region Header inspection
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("+++++++++++++++++++++++++++[ Export Service ]++++++++++++++++++++++++++++++");
                LOG.Debug("Analizing request...");
                LOG.Debug(string.Format("RequestType : {0}", request.RequestType));
                LOG.Debug(string.Format("UserAgent : {0}", request.UserAgent));
                LOG.Debug(string.Format("UserHostAddress : {0}", request.UserHostAddress));
                LOG.Debug(string.Format("UserHostName : {0}", request.UserHostName));
                LOG.Debug(string.Format("ContentType : {0}", request.ContentType));
                LOG.Debug(string.Format("HttpMethod : {0}", request.HttpMethod));

                if (request.QueryString != null && request.QueryString.Count > 0)
                {
                    LOG.Debug(string.Format("The query string: {0}", request.QueryString));
                    foreach (var key in request.QueryString.Keys)
                    {
                        LOG.Debug(string.Format("[QueryString] Key: {0}, Value: {1}", key,
                                                request.QueryString[(string)key]));
                    }
                }
                if (request.Headers != null && request.Headers.Count > 0)
                {
                    LOG.Debug(string.Format("Headers collection: {0}", request.Headers));
                    foreach (var key in request.Headers.Keys)
                    {
                        LOG.Debug(string.Format("[Header] Key: {0}, Value: {1}", key, request.Headers[(string)key]));
                    }
                }
                if (request.Form != null && request.Form.Count > 0)
                {
                    LOG.Debug(string.Format("Form values: {0}", request.Form));
                    foreach (var key in request.Form.Keys)
                    {
                        LOG.Debug(string.Format("[FormValue] Key: {0}, Value: {1}", key, request.Form[(string)key]));
                    }
                }
                if (request.Files != null && request.Files.Count > 0)
                {
                    LOG.Debug(string.Format("The Files collection: {0}", request.Files));
                    foreach (var key in request.Files.Keys)
                    {
                        var file = request.Files[(string)key];
                        LOG.Debug(
                            string.Format("[PostedFile] Key: {0}, FileName: {1}, ContentType: {2}, ContentLength: {3}",
                                          key, file.FileName, file.ContentType, file.ContentLength));
                    }
                }
                LOG.Debug("Analisys finished.");
                LOG.Debug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            }
            #endregion

            var requestStr = HttpUtility.UrlDecode(request.QueryString.ToString());
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug(string.Format("Request string readed: {0}", requestStr));
            }
            var service = request.QueryString["Service"];
            var method = request.QueryString["Method"];
            var parameters = request.QueryString["Parameters"];
            var sb = new StringBuilder();
            sb.Append("{")
                .Append("'Service':'").Append(service).Append("'")
                .Append(",'Method':'").Append(method).Append("'")
                .Append(",'Parameters':").Append(parameters);
            sb.Append("}");
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug(string.Format("Request string readed to process: {0}", sb));
            }
            return Processor.Decode(sb.ToString());
        }
        
        public void WriteResponse(ServiceRequest request, ServiceResponse response)
        {
            HttpContext.Current.Response.ContentType =
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            var builder = IoCFactory.Resolve<IExcelFileBuilder>();
            using (var ms = new MemoryStream())
            {
                builder.BuildFile(ms, (QuerySpecification) request.Parameters[0], (QueryResult) response.Result);
                ms.WriteTo(HttpContext.Current.Response.OutputStream);
            }
        }

        public void WriteResponse(ServiceResponse response)
        {
            throw new InvalidOperationException();
            //var encodedResponse = Processor.Encode(response);
            //HttpContext.Current.Response.ContentType =
            //    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            //HttpContext.Current.Response.Write(encodedResponse);
        }
    }
}
